/*
 * @(#)OrderController.java 2021年3月8日
 *
 * Copyright (c) 2010 by rayootech.com. All rights reserved.
 */
package com.nuctech.order.controller;

import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.fastjson.JSON;
import com.nuctech.common.entity.Order;
import com.nuctech.common.entity.Product;
import com.nuctech.order.service.OrderService;
import com.nuctech.order.service.ProductService;

import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;

/**
 * 订单接口控制器
 *
 * @author lilu
 * @date 2021年3月8日
 * @since 1.0.0
 */
@Slf4j
@RestController
@RequestMapping("/order")
public class OrderController {

	/** 开启压力测试 true-开启，false-关闭 **/
	private final static boolean PRESSURE_TEST = false;

	/** 开启降级测试 true-开启，false-关闭 **/
	private final static boolean DEMOTION_TEST = false;

//	@Autowired
//	private RestTemplate restTemplate;

	@Autowired
	private OrderService orderService;

	@Autowired
	private ProductService productService;

//	@Autowired
//	private DiscoveryClient discoveryClient;

	@Autowired
	private RocketMQTemplate rocketMQTemplate;

	/**
	 * 获取订单信息
	 *
	 * @author lilu
	 * @date 2021/3/9 5:24 下午
	 * @since 1.0.0
	 *
	 * @param oid
	 * @return com.nuctech.common.entity.Order
	 * @throws
	 */
	@GetMapping("/get/{oid}")
	public Order get(@PathVariable("oid") Integer oid) {
		return this.orderService.get(oid);
	}
	/**
	 * 创建订单
	 *
	 * @author lilu
	 * @date 2021年3月8日 下午4:04:36
	 * @since 1.0.0
	 *
	 * @param pid
	 * @return
	 */
	@PostMapping("/product/{pid}")
	public Order order(@PathVariable("pid") Integer pid) {
		// 微服务实例调用负载均衡 -----start
		// 调用商品微服务查询商品信息
//		Product product = this.restTemplate.getForObject("http://localhost:8081/product/" + pid, Product.class);

		// 获取Nacos服务实例
		// 1、自定义负载均衡-随机选择
//		List<ServiceInstance> instances = this.discoveryClient.getInstances("service-product");
//		ServiceInstance instance = instances.get(RandomUtil.randomInt(instances.size()));
//		Product product = this.restTemplate.getForObject(
//			StrUtil.format("http://{}:{}/product/{}", instance.getHost(), instance.getPort(), pid), Product.class);
		// 2、基于Ribbon实现负载均衡
//		Product product = this.restTemplate.getForObject(
//			StrUtil.format("http://service-product/product/{}", pid), Product.class);
		// 3、基于Feign商品微服务调用接口
		Product product = this.productService.product(pid);
		if (product.getPid() < 0) {
			return new Order().setOid(-1).setPname("下单失败");
		}
		// 微服务实例调用负载均衡 -----end

		if (PRESSURE_TEST) {
			// 模拟调用商品微服务需要2秒钟的时间
			try {
				Thread.sleep(2000);
			} catch (InterruptedException e) {
			}
		}

		log.info("查询到{}号商品信息，内容是：{}", pid, JSON.toJSONString(product));

		// 下单
		Order order = new Order()
				.setUid(1)
				.setUsername("测试用户")
				.setPid(product.getPid())
				.setPname(product.getPname())
				.setPprice(product.getPprice())
				.setNumber(1);
		if (!PRESSURE_TEST) {
			this.orderService.createOrder(order);
		}
		log.info("创建订单成功，订单信息为：{}", JSON.toJSONString(order));

		// 向MQ中投递下单成功的消息
		String topic = "order-topic";
		this.rocketMQTemplate.convertAndSend(topic, order);

		return order;
	}

	/**
	 * 创建订单TX
	 *
	 * @author lilu
	 * @date 2021年3月8日 下午4:04:36
	 * @since 1.0.0
	 *
	 * @param pid
	 * @return
	 */
	@PostMapping("/product/tx/{pid}")
	public Order orderTx(@PathVariable("pid") Integer pid) {
		Product product = this.productService.product(pid);
		if (product.getPid() < 0) {
			return new Order().setOid(-1).setPname("下单失败");
		}

		log.info("查询到{}号商品信息，内容是：{}", pid, JSON.toJSONString(product));

		// 下单
		Order order = new Order()
				.setUid(1)
				.setUsername("测试用户")
				.setPid(product.getPid())
				.setPname(product.getPname())
				.setPprice(product.getPprice())
				.setNumber(1);

		this.orderService.createOrderBefore(order);
		log.info("创建订单成功，订单信息为：{}", JSON.toJSONString(order));

		return order;
	}

	/**
	 * 创建分布式事务订单
	 *
	 * @author lilu
	 * @date 2021/3/28 12:39 下午
	 * @since 1.0.0
	 *
	 * @param pid
	 * @return com.nuctech.common.entity.Order
	 * @throws
	 */
	@PostMapping("/product/dt/{pid}")
	public Order orderDT(@PathVariable("pid") Integer pid) {
		return this.orderService.createOrderDT(pid);
	}

	@GetMapping("/message")
	public String message() {
		return this.orderService.message("M");
	}

	@GetMapping("/message1")
	public String message1() {
		this.orderService.message("M");
		return "message1";
	}

	// 模拟异常
	int i = 0;
	@GetMapping("/message2")
	public String message2() {
		if (DEMOTION_TEST) {
			i++;
			// 异常比例为0.33
			if (i % 3 == 0) {
				throw new RuntimeException();
			}
		}
		this.orderService.message("M");
		return "message2";
	}

	// 实现热点参数限流规则
	@GetMapping("/message3")
	@SentinelResource("message3")// 用于标识一个Sentinel资源
	public String message3(String name, Integer age) {
		return StrUtil.format("message3,name:{},age:{}", name, age);
	}

}
